package tadp.tp.domain;

import java.util.ArrayList;
import java.util.List;
import comparadores.PorEstado;
import Observers.Observador;
import accionesPosteriores.AccionPosterior;
import limites.Limite;
import tadp.tp.domain.condiciones.Condicion;

public class OrganizadorDeReuniones {
	private HomePersonas personas;
	private Edificio edificio;
	private Proyecto proyecto;

	public OrganizadorDeReuniones(HomePersonas unHome, Edificio unEdi,Proyecto unP) {
		this.setPersonas(unHome);
		this.edificio = unEdi;
		this.proyecto = unP;
	}
	
	public Reunion organizarReunion(List<Condicion> condiciones, Limite unLimite,
			String unHorarioI, String unHorarioF, Fecha fechaReunion, ArrayList<AccionPosterior> accionesPosteriores,List<Observador> unosObservadores) {   
		Reunion reunion = new Reunion(this.personasSeleccionadas(condiciones,unLimite,fechaReunion), 
				this.edificio, new HorarioDeReuniones(unHorarioI, unHorarioF, fechaReunion),unosObservadores);
		ArrayList<Reservable> reservables = new ArrayList<Reservable>();
		reservables.addAll(reunion.getPersonas());
		reservables.add(this.edificio.salaDisponible(unHorarioI, unHorarioF, fechaReunion)); // agrega UNA SALA SI LA ENCUENTRA
		reunion.reservar(reservables, unHorarioI, unHorarioF, fechaReunion); 
		this.proyecto.agregarCostos(reunion.costoReunion());
		
		//Agregado Brian
		reunion.setFecha(fechaReunion);
		for(AccionPosterior accionPosterior : accionesPosteriores) {
//			if(accionPosterior != null) {
				accionPosterior.ejecutar(reunion);
//			}
		}
		for(Persona persona : reunion.getPersonas()) {
			if(persona.getAccionDeUsuario() != null) {
				persona.getAccionDeUsuario().ejecutar(persona, reunion);
			}
		}
		return reunion;
	}

	public List<Persona> personasSeleccionadas(List<Condicion> condiciones,Limite unLimite,Fecha fechaReunion) {
		List<Persona> personasConCondiciones = new ArrayList<Persona>();
		List<Persona> personasLimitadas = new ArrayList<Persona>();
		List<Persona> personasFinales= new ArrayList<Persona>();
		if (condiciones != null) {
			for (Persona unaPersona : this.getPersonas().todasLaspersonas()) {
				if (unaPersona.cumpleCondiciones(condiciones)) {
					personasConCondiciones.add(unaPersona);
				}
			}
		} else {
			personasConCondiciones.addAll(this.getPersonas().todasLaspersonas());
		}
		/* ----- Hasta aca se filtra por condiciones ---- */
		if(unLimite != null){
			
			for(Persona unaPersona: personasConCondiciones){
				if(unLimite.tieneLimite(unaPersona)){
					personasLimitadas.add(unaPersona);
				}else{
					personasFinales.add(unaPersona);
				}
			}
			/* ---- A las personas Limitadas les aplico los filtros ----*/
			
				new PorEstado(this.edificio, fechaReunion).ordenar(personasLimitadas);
				personasFinales.addAll(personasLimitadas.subList(0, unLimite.getCantidad()));
		
		}else{//si no tengo limites, pongo todos los que cumplen condiciones
			personasFinales.addAll(personasConCondiciones);
			
		}
			
		return personasFinales;
	}	
	
	public void necesitoProyectLiderPara(Reunion reunion)
	{
		for (Persona unaPersona : this.getPersonas().todasLaspersonas()) 
		{
			if (unaPersona.getRol().equals("proyect lider")) 
			{
				reunion.getPersonas().add(unaPersona);
				unaPersona.getAgenda().agendarEntre(reunion.getHorario().getHoraComienzo(),
						reunion.getHorario().getHoraFin(), reunion.getHorario().getFecha()); 
				break;// TODO Auto-generated method stub
			}
		}

	}

//	public void reorganizarReunion(Reunion reunion, Fecha fecha) {
//		ArrayList<Reservable> cosasAReservar=new ArrayList<Reservable>();
//		cosasAReservar.add(this.edificio.salaDisponible(reunion.getHorario().getHoraComienzo(), reunion.getHorario().getHoraFin(), fecha));
//		cosasAReservar.addAll(reunion.getPersonas());
//		reunion.reservar(cosasAReservar, reunion.getHorario().getHoraComienzo(), reunion.getHorario().getHoraFin(), fecha);
		
//	}

	public HomePersonas getPersonas() {
		return personas;
	}

	public void setPersonas(HomePersonas personas) {
		this.personas = personas;
	}

	public Edificio getEdificio() {
		return this.edificio;
	}

	public Persona seleccionarPersonaExtra(List<Condicion> buildCondicion) {
		for(Persona unaPersona: this.getPersonas().todasLaspersonas()){
			if(unaPersona.cumpleCondiciones(buildCondicion)){
				return unaPersona;
			}
		}
		return null;
	}
	

}
